var gamejs = require("gamejs");

/**
 * InputManager : Provides a simple way to manage events.
 */

/**
 * Creates a InputManager object.
 * It can manage mouse click and mouse motion, see processEvents(events)
 * and addClickCheck(..) for more detailed info.
 */
var InputManager = exports.InputManager = function () {
	this.mousePos = null;
	this.clickChecks = [];
};

/**
 * Adds a check when processing a mouse click.
 * It adds a property named propertyToSet to this InputManager object.
 * The processEvents(events) method then sets this property to true
 * if it finds a mouse click in the given boundingRect.
 * You can know if there is a click by checking the propertyToSet
 * property of this InputManager object.
 * This property remains true till the next processEvents(..) call.
 * 
 * @param {gamejs.Rect} boundingRect The rect where to check for clicks.
 * @param {String} propertyToSet The property name to set to true when
 * there is a click on the boundingRect.
 * This string MUST contain a valid property name, we suggest to use
 * something like 'clickOnValue', where 'Value' is the name of the action
 * that the click will do.
 * Example: if your InputManager object is called 'inMng', and you have a
 * gamejs.Sprite object called 'pause' to use as a pause button, then you
 * can do like this:
 * inMng.addClickCheck(pause.rect, "clickOnPause");
 * inMng.processEvents(gamejs.event.get());
 * if(inMng.clickOnPause) {
 * 		//going to pause
 * }
 */
InputManager.prototype.addClickCheck = function (boundingRect, propertyToSet) {
	this.clickChecks.push({toCheck : boundingRect, toSet : propertyToSet});
	
	if(this[propertyToSet] !== undefined) {
		throw new Error("Another property with the same name is already present");
	}
	this[propertyToSet] = false;
};

/**
 * Process the given list of gamejs.Event:
 *  - it sets to true the properties added with addClickCheck,
 * 		if there is a click on the related rect;
 * - it sets the new mouse position if there is a mouse motion.
 * 
 * @param {Array} An array of gamejs.Event, it's very strictly recommended
 * the use of the list retrieved calling gamejs.event.get().
 */
InputManager.prototype.processEvents = function (events) {
	//reset results of previous check
	for(tmpVar in this) {
		//this trick forces us to not use
		//properties of type 'boolean' in InputManager,
		//is not a problem for now...
		if(typeof this[tmpVar] == "boolean") {
			this[tmpVar] = false;
		}
	}
	
	//process the events list
	for(i = 0; i < events.length; i++) {
		var currentEvent = events[i];
		
		//check if this event is a mouse click
		if(currentEvent.type === gamejs.event.MOUSE_UP) {
			var clickPos = currentEvent.pos;
			//select the elements which collide with the mouse click
			var clicked = this.clickChecks.filter(function (clickCheck) {
				return clickCheck.toCheck.collidePoint(clickPos);
			});
			
			//if clicked on zero or two (or more) elements, do nothing
			if(clicked.length == 1) {
				this[clicked[0].toSet] = true;
			}
		}
		
		//check if this event is a mouse motion
		if(currentEvent.type === gamejs.event.MOUSE_MOTION) {
			//save the mouse position
			this.mousePos = currentEvent.pos;
		}
	}
};

/**
 * Returns the last mouse position stored.
 * 
 * @throws {Error} If no mouse event is been processed yet.
 */
InputManager.prototype.getMousePosition = function() {
	if( ! this.mousePos) {
		throw new Error("No mouse event is been processed yet")
	}
	
	return this.mousePos;
};